// global.h
#ifndef MYSTRUCT_H
#define MYSTRUCT_H

#include <iostream>
#include <list>
#include <set>
#include <cmath>
#include <unordered_set>

struct Point {
    int x;
    int y;

    friend std::istream& operator>>(std::istream& in, Point& p){
        in >> p.x >> p.y;
        return in;
    }
    friend std::ostream& operator<<(std::ostream& out, Point& p){
        out << p.x << " " << p.y << " ";
        return out;
    }

    bool operator==(const Point& p){
        return (p.x == x && p.y == y);
    }

    Point operator-(const Point& p) const {
        return Point(x - p.x, y - p.y);
    }

    Point(){}
    Point(int x, int y):x(x), y(y){}
    
    int Distance(Point& p){
        return abs(p.x-x) + abs(p.y-y);
    }
    
};

// 货物
struct Cargo{
    Point p;
    int val;
    int frame; // 在哪一帧加入

    float price; // 当前实现为价格/距离

    friend std::istream& operator>>(std::istream& in, Cargo& cargo){
        in >> cargo.p >> cargo.val;
        return in;
    }

    friend std::ostream& operator<<(std::ostream& out, Cargo& cargo){
        out << "[cargo(" << cargo.p << "), val: " << cargo.val << ", price: " << cargo.price << "]";
        return out;
    }

    bool operator==(const Cargo& c) const {
        return (c.p.x == p.x && c.p.y == p.y && c.val == val && c.frame == frame);
    }

    Cargo(){}
    Cargo(Point p, int val):p(p), val(val){}
    Cargo(Point p, int val, int frame):p(p), val(val), frame(frame), price(0){}
    Cargo(Point p, int val, int frame, int distance):p(p), val(val), frame(frame){
        if(distance == 0) price = 0; // 无路可去
        else price = (float)val/distance; // price等于价值/时间
    }
};
struct CargoCompare {
    bool operator()(Cargo a, Cargo b) const {
        return a.price > b.price; // 从大到小
    }
};

struct CargoHash {
    std::size_t operator()(const Cargo& cargo) const {
        std::size_t h1 = std::hash<int>{}(cargo.p.x);
        std::size_t h2 = std::hash<int>{}(cargo.p.y);
        std::size_t h3 = std::hash<int>{}(cargo.val);
        std::size_t h4 = std::hash<int>{}(cargo.frame);
        return h1 ^ h2 ^ h3 ^ h4;
    }
};

#endif